home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / CLOUDL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  7.1 KB  |  286 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6.  
  7. #ifndef __sgi
  8. /* Most math.h's do not define float versions of the math functions. */
  9. #define expf(x) ((float)exp((x)))
  10. #endif
  11.  
  12. static float ttrans[2];
  13. static float transx, transy, rotx, roty;
  14. static int ox = -1, oy = -1;
  15. static int mot;
  16. #define PAN    1
  17. #define ROT    2
  18.  
  19. void
  20. pan(int x, int y) {
  21.     transx +=  (x-ox)/500.;
  22.     transy -= (y-oy)/500.;
  23.     ox = x; oy = y;
  24.     glutPostRedisplay();
  25. }
  26.  
  27. void
  28. rotate(int x, int y) {
  29.     rotx += x-ox;
  30.     if (rotx > 360.) rotx -= 360.;
  31.     else if (rotx < -360.) rotx += 360.;
  32.     roty += y-oy;
  33.     if (roty > 360.) roty -= 360.;
  34.     else if (roty < -360.) roty += 360.;
  35.     ox = x; oy = y;
  36.     glutPostRedisplay();
  37. }
  38.  
  39. void
  40. motion(int x, int y) {
  41.     if (mot == PAN) pan(x, y);
  42.     else if (mot == ROT) rotate(x,y);
  43. }
  44.  
  45. void
  46. mouse(int button, int state, int x, int y) {
  47.     if(state == GLUT_DOWN) {
  48.     switch(button) {
  49.     case GLUT_LEFT_BUTTON:
  50.         mot = PAN;
  51.         motion(ox = x, oy = y);
  52.         break;
  53.     case GLUT_RIGHT_BUTTON:
  54.         mot = ROT;
  55.         motion(ox = x, oy = y);
  56.         break;
  57.     case GLUT_MIDDLE_BUTTON:
  58.         break;
  59.     }
  60.     } else if (state == GLUT_UP) {
  61.     mot = 0;
  62.     }
  63. }
  64.  
  65. void
  66. animate(void) {
  67.     ttrans[0] += .010f;
  68.     if (ttrans[0] == 1.0f) ttrans[0] = 0.0f;
  69.     ttrans[1] -= .020f;
  70.     if (ttrans[1] <= 0.0f) ttrans[1] = 1.0f;
  71.     glutPostRedisplay();
  72. }
  73.  
  74. void xfunc(void) {
  75.     static state = 1;
  76.     glutIdleFunc((state ^= 1) ? animate : NULL);
  77. }
  78.  
  79. void help(void) {
  80.     printf("Usage: cloudl [image]\n");
  81.     printf("'h'            - help\n");
  82.     printf("'x'            - toggle cloud motion\n");
  83.     printf("left mouse     - pan\n");
  84.     printf("middle mouse   - rotate\n");
  85. }
  86.  
  87. void init(char *filename) {
  88.     GLfloat fog_color[4], fog_density = 0.05, density, far_cull;
  89.     unsigned *image;
  90.     int width, height, components;
  91.     if (filename) {
  92.     image = read_texture(filename, &width, &height, &components);
  93.     if (image == NULL) {
  94.         fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  95.             filename);
  96.         exit(EXIT_FAILURE);
  97.     } else {
  98.         printf("%d x %d image loaded\n", width, height);
  99.     }
  100.     if (components != 1 && components != 2) {
  101.         printf("must be a l or la image\n");
  102.         exit(EXIT_FAILURE);
  103.     }
  104.     if (components == 1) {
  105.         /* hack for RE */
  106.         int i;
  107.         GLubyte *p = (GLubyte *)image;
  108.         for(i = 0; i < width*height; i++) {
  109.         p[i*4+3] = p[i*4+0];
  110.         }
  111.         components = 2;
  112.     }
  113.     } else {
  114.     int i, j;
  115.     unsigned char *img;
  116.     components = 4; width = height = 512;
  117.     image = (unsigned *) malloc(width*height*sizeof(unsigned));
  118.     img = (unsigned char *)image;
  119.     for (j = 0; j < height; j++)
  120.         for (i = 0; i < width; i++) {
  121.         int w2 = width/2, h2 = height/2;
  122.         if (i & 32)
  123.             img[4*(i+j*width)+0] = 0xff;
  124.         else
  125.             img[4*(i+j*width)+1] = 0xff;
  126.         if (j&32)
  127.             img[4*(i+j*width)+2] = 0xff;
  128.         if ((i-w2)*(i-w2) + (j-h2)*(j-h2) > 64*64 &&
  129.             (i-w2)*(i-w2) + (j-h2)*(j-h2) < 300*300) img[4*(i+j*width)+3] = 0xff;
  130.         }
  131.  
  132.     }
  133.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  134.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  135.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  136.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  137.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  138.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  139.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  140.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  141.                  image);
  142.     /*glEnable(GL_TEXTURE_2D);*/
  143.     glMatrixMode(GL_PROJECTION);
  144.     glLoadIdentity();
  145.     gluPerspective(50.,1.,.1,far_cull = 10.);
  146.     glMatrixMode(GL_MODELVIEW);
  147.     glLoadIdentity();
  148.     glTranslatef(0.,0.,-5.5);
  149.  
  150.     density = 1.- expf(-5.5 * fog_density * fog_density *
  151.                   far_cull * far_cull);
  152.  
  153. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  154. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  155.     density = MAX(MIN(density, 1.), 0.);
  156.  
  157.     fog_color[0] = .23*.2 + density *.57*.2;
  158.     fog_color[1] = .35*.2 + density *.45*.2;
  159.     fog_color[2] = .78*.5 + density *.22*.2;
  160.  
  161.     glClearColor(fog_color[0], fog_color[1], fog_color[2], 1.f);
  162.  
  163.     glFogi(GL_FOG_MODE, GL_EXP2);
  164.     glFogf(GL_FOG_DENSITY, fog_density);
  165.     glFogfv(GL_FOG_COLOR, fog_color);
  166.     if (fog_density > 0)
  167.     glEnable(GL_FOG);
  168.     glLineWidth(2.0f);
  169.     glEnable(GL_LINE_SMOOTH);
  170.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  171.     glPointSize(10.f);
  172.     glEnable(GL_POINT_SMOOTH);
  173.     glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
  174. }
  175.  
  176. void draw_base(void) {
  177.     glColor4f(.1, .3, .1, 1.0);
  178.     glBegin(GL_QUADS);
  179.     glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f);
  180.     glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f,  1.f);
  181.     glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f,  1.f);
  182.     glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f);
  183.     glEnd();
  184. }
  185.  
  186. void draw_runway(void) {
  187.     glColor4f(.1, .1, .1, 1.0);
  188.     glPushMatrix();
  189.     glScalef(.1f, 1.f, 1.f);
  190.     glBegin(GL_QUADS);
  191.     glTexCoord2f(0, 0); glVertex3f(-1.f, 0.f, -1.f);
  192.     glTexCoord2f(0, 1); glVertex3f(-1.f, 0.f,  1.f);
  193.     glTexCoord2f(1, 1); glVertex3f( 1.f, 0.f,  1.f);
  194.     glTexCoord2f(1, 0); glVertex3f( 1.f, 0.f, -1.f);
  195.     glEnd();
  196.     glPopMatrix();
  197. }
  198.  
  199. void draw_lights(void) {
  200.     int i;
  201.  
  202.     glEnable(GL_BLEND);
  203.     glColor4f(.7f, .7f, .1f, 1.0);
  204.     glPushMatrix();
  205.     glScalef(.1f, 1.f, 1.f);
  206.     glEnable(GL_POINT_SMOOTH);
  207.     for(i = 0; i <= 20; i++) {
  208.     glPointSize((float)i/2.);
  209.     glBegin(GL_POINTS);
  210.     glVertex3f(-1.f, 0.f, -1.f+2.f/20*i);
  211.     glVertex3f( 1.f, 0.f, -1.f+2.f/20*i);
  212.     glEnd();
  213.     }
  214.     glPopMatrix();
  215.     glDisable(GL_BLEND);
  216. }
  217.  
  218. void
  219. draw_clouds(void) {
  220.     glEnable(GL_BLEND);
  221.     glEnable(GL_TEXTURE_2D);
  222.     glMatrixMode(GL_TEXTURE);
  223.     glPushMatrix();
  224.     glTranslatef(ttrans[0], ttrans[1], 0.);
  225.     glColor4f(1.f, 1.f, 1.f, 1.0);
  226.     glBegin(GL_QUADS);
  227.     glTexCoord2f(0, 0); glVertex3f(-1., .2, -1.);
  228.     glTexCoord2f(0, 5); glVertex3f(-1., .2,  1.);
  229.     glTexCoord2f(5, 5); glVertex3f( 1., .2,  1.);
  230.     glTexCoord2f(5, 0); glVertex3f( 1., .2, -1.);
  231.     glEnd();
  232.     glPopMatrix();
  233.     glMatrixMode(GL_MODELVIEW);
  234.     glDisable(GL_TEXTURE_2D);
  235.     glDisable(GL_BLEND);
  236. }
  237.  
  238. void display(void) {
  239.     glClear(GL_COLOR_BUFFER_BIT);
  240.  
  241.     glPushMatrix();
  242.     glTranslatef(transx, transy, 0.f);
  243.     glRotatef(rotx, 0., 1., 0.);
  244.     glRotatef(roty, 1., 0., 0.);
  245.     glScalef(10,1,10);
  246.     glTranslatef(0.f,-1.f,0.f);
  247.     draw_base();
  248.     draw_runway();
  249.     draw_lights();
  250.     draw_clouds();
  251.     glPopMatrix();
  252.     glutSwapBuffers();
  253. }
  254.  
  255. void reshape(int w, int h) {
  256.     glViewport(0, 0, w, h);
  257. }
  258.  
  259. /*ARGSUSED1*/
  260. void
  261. key(unsigned char key, int x, int y) {
  262.     switch(key) {
  263.     case 'x': xfunc(); break;
  264.     case 'h': help(); break;
  265.     case '\033': exit(EXIT_SUCCESS); break;
  266.     default: break;
  267.     }
  268.     glutPostRedisplay();
  269. }
  270.  
  271. int main(int argc, char** argv) {
  272.     glutInitWindowSize(512, 512);
  273.     glutInit(&argc, argv);
  274.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
  275.     (void)glutCreateWindow(argv[0]);
  276.     init(argc == 1 ? "data/clouds.bw" : argv[1]);
  277.     glutDisplayFunc(display);
  278.     glutKeyboardFunc(key);
  279.     glutReshapeFunc(reshape);
  280.     glutMouseFunc(mouse);
  281.     glutMotionFunc(motion);
  282.     glutIdleFunc(animate);
  283.     glutMainLoop();
  284.     return 0;
  285. }
  286.